package readWrite;

import org.junit.Test;

import java.io.*;
import java.sql.SQLOutput;

/*
* 一:流的分类:
* 1:操作数据单位:字节流,字符流
* 2:数据的流向:输入流,输出流
* 3:流的角色:节点流,处理流
*
* 二:流的体系结构
* 抽象基类              节点流
* InputStream       FileInputStream
* OutputString      FileOutputString
* Reader            FileReader
* Writer            FileWriter
*
* */
public class FileReadWriteTest {
    public static void main(String[] args) {
        //相对路径:相对于当前工程
        File file = new File("hi1.txt");
        System.out.println(file.getAbsoluteFile());
    }
    /*
    * 将hi.txt文件内容读入程序内存,并输出到控制台
    *
    * 说明点:
    *   1:read()的理解,返回读入的一个字符,如果达到文件末尾,返回-1
    *   2:异常处理:为了保证流资源一定可以执行关闭操作,需要使用try-catch-finally来处理
    *   3:读入的文件一定要存在,否则就会包文件不存在的异常
    * */
    @Test
    public void testRileReader() throws IOException {
        FileReader fileReader = null;
        try {
            //1:实例化File对象
            //相对路径:相对于当前Module
            File file = new File("hi.txt");
            System.out.println(file.getAbsoluteFile());

            //2:提供具体的流
            fileReader = new FileReader(file);

            //3:数据的读入
            //返回文件的字符,如果读到末尾,返回-1

            //方式一:
//        int read = fileReader.read();
//        while (read != -1){
//            System.out.print((char)read);
//            read = fileReader.read();
//        }
            //方式二:
            int read1;
            while ((read1 = fileReader.read()) != -1){
                System.out.print((char)read1);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4:流的关闭
            if (fileReader != null){
                fileReader.close();
            }
        }
    }

    /*
    * 使用read的重载方法
    * */
    @Test
    public void test1(){
        //1:File类的实例化
        File file = new File("hi.txt");

        //2:IO流的实例化
        try {
            FileReader reader = new FileReader(file);
            //3:读入的操作/写出的操作
            //read(char[] cbuf):返回每次读入数组中的字符的个数,如果达到文件末尾,返回-1
            char[] cbuf = new char[5];
            int len;
            while ((len = reader.read(cbuf)) != -1){

                //方式一:
                //错误的写法
//                for (int i = 0; i < cbuf.length; i++) {
//                    System.out.print(cbuf[i]);
//                }
                //正确的写法
//                for (int i = 0; i < len; i++) {
//                    System.out.print(cbuf[i]);
//                }

                //方式二:
                //错误的写法:对应方式一的错误
//                String s = new String(cbuf);

                String s = new String(cbuf, 0, len);
                System.out.print(s);
            }
            int read = reader.read(cbuf);

            //4:流资源的关闭
            reader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
        }
    }

    /*
    * 从内存中写出数据到硬盘文件中
    *
    * 说明:
    * 1:输出操作,对应的文件可以不存在
    *       如果不存在,会自动创建文件
    *       如果存在
    *           如果流使用的构造器:FileWriter(file,false),会对原有文件覆盖
    *           如果流使用的构造器:FileWriter(file,true),会在原有文件上追加内容
    *
    * */
    @Test
    public void testFileWriter(){
        //1:提供File类的对象:指明写出到的文件
        File file = new File("hello.txt");

        //2:提供FileWriter的对象,用于数据的写出
        FileWriter writer = null;
        try {
            writer = new FileWriter(file);
            //3:写出的操作
            writer.write("I have a dream\n");
            writer.write("You neet to have a dream");

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //4:流资源的关闭
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /*
    * 读文件,然后再写文件
    * */
    @Test
    public void testFileReaderFileWriter() throws IOException {
        FileReader fileReader = null;
        FileWriter fileWriter = null;
        try {
            //1:创建File类的对象,指明读入和写出的文件
            File srcFile = new File("hello.txt");
            File destFile = new File("hello1.txt");
            //2:创建输入流和输出流的对象
            fileReader = new FileReader(srcFile);
            fileWriter = new FileWriter(destFile);

            //3:数据的读入和写出操作
            char[] cbuf = new char[5];
            int len;//记录每次读入到数组中的字符的个数
            while ((len = fileReader.read(cbuf)) != -1){
                //每次写出len个字符
                fileWriter.write(cbuf,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4:流资源的关闭
            try {
                if (fileWriter != null)
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fileReader != null)
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
